package com.pdf.demo.util;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.BaseFont;

import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.*;
import java.util.Map;

/**
 * 通过FreeMarker生成PDF
 */
public class PdfUtil {

    private static final String PATH = Thread.currentThread().getContextClassLoader().getResource("").getPath();

    private static final String TEMPLATE = PATH+"templates";//模板存储路径

    private static final String CONTRACT = PATH+"templates";//pdf生成路径

    //柱形图路径
    private static final String IMAGE_PATH = PATH+"static/images/";
    //字体路径
    private static final String TYPEFACE_PATH = PATH+"static/typeface/";

    private static final String PDFNAME = "pdfDemo";//pdf文件名
    private static final String HTMLNAME = "pdfDemo";//html文件名

    public static void contractHandler(String templateName,
                                       Map<String, Object> paramMap) throws Exception {
        // 获取本地模板存储路径、合同文件存储路径
        String templatePath = TEMPLATE;
        String contractPath = CONTRACT;
        // 组装html和pdf合同的全路径URL
        String localHtmlUrl = contractPath +"/"+ HTMLNAME + ".html";
        String localPdfPath = contractPath ;
        // 判断本地路径是否存在如果不存在则创建
        File localFile = new File(localPdfPath);
        if (!localFile.exists()) {
            localFile.mkdirs();
        }
        String localPdfUrl = localFile +"/"+ PDFNAME + ".pdf";
        templateName = templateName + ".ftl";
        htmHandler(templatePath, templateName, localHtmlUrl, paramMap);// 生成html合同
        pdfHandler(localHtmlUrl, localPdfUrl);// 根据html合同生成pdf合同
        //deleteFile(localHtmlUrl);// 删除html格式合同

        System.out.println("PDF生成成功");
    }

    public static void contractHandler(String templateName,
                                       Map<String, Object> paramMap, String localPdfUrl) throws Exception {
        // 获取本地模板存储路径、合同文件存储路径
        String templatePath = TEMPLATE;
        String contractPath = CONTRACT;
        // 组装html和pdf合同的全路径URL
        String localHtmlUrl = contractPath +"/"+ HTMLNAME + ".html";
        String localPdfPath = contractPath ;
        // 判断本地路径是否存在如果不存在则创建
        File localFile = new File(localPdfPath);
        if (!localFile.exists()) {
            localFile.mkdirs();
        }
        //String localPdfUrl = localFile +"/"+ PDFNAME + ".pdf";
        templateName = templateName + ".ftl";
        htmHandler(templatePath, templateName, localHtmlUrl, paramMap);// 生成html合同
        pdfHandler(localHtmlUrl, localPdfUrl);// 根据html合同生成pdf合同
        //deleteFile(localHtmlUrl);// 删除html格式合同

        System.out.println("PDF生成成功");
    }

    /**
     * 生成html合同
     * @param templatePath
     * @param templateName
     * @param htmUrl
     * @param paramMap
     * @throws Exception
     */
    private static void htmHandler(String templatePath, String templateName,
                                   String htmUrl, Map<String, Object> paramMap) throws Exception {
        Configuration cfg = new Configuration();
        cfg.setDefaultEncoding("UTF-8");
        cfg.setDirectoryForTemplateLoading(new File(templatePath));
        Template template = cfg.getTemplate(templateName);
        File outHtmFile = new File(htmUrl);
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outHtmFile)));
        template.process(paramMap, out);
        out.close();
    }

    /**
     * 根据html合同生成pdf合同
     * @param htmUrl
     * @param pdfUrl
     * @throws Exception
     */
    private static void pdfHandler(String htmUrl, String pdfUrl)
            throws Exception {
        File htmFile = new File(htmUrl);
        File pdfFile = new File(pdfUrl);
        String url = htmFile.toURI().toURL().toString();
        OutputStream os = new FileOutputStream(pdfFile);
        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocument(url);

        org.xhtmlrenderer.pdf.ITextFontResolver fontResolver = renderer.getFontResolver();
        // 显示中文
        String fontPath=TYPEFACE_PATH+"msyh.ttc";
		fontResolver.addFont(fontPath,BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
		String imagePath = "file:"+IMAGE_PATH;
        //设置打印的图片的前缀--解决图片的相对路径问题---注意："file:/"必须存在
        renderer.getSharedContext().setBaseURL(imagePath);
        renderer.layout();
        try {
            renderer.createPDF(os);
        } catch (Exception e) {
            e.printStackTrace();
        }
        os.close();
    }

    /**
     * 删除html格式合同
     * @param fileUrl
     */
    private static void deleteFile(String fileUrl) {
        File file = new File(fileUrl);
        file.delete();
    }

    /**
     * @author Reverse_XML
     * 将多个PDF合并成一个PDF
     * @param files 源PDF路径
     * @param outputPath 合并后输出的PDF路径
     * @param outputFileName 合并后输出的PDF文件名
     */
    public static void mergePDF(String[] files, String outputPath, String outputFileName) {
        String sep = java.io.File.separator;
        Document document = null;
        PdfCopy copy = null;
        PdfReader reader = null;
        try {
            document = new Document(new PdfReader(files[0]).getPageSize(1));
            copy = new PdfCopy(document, new FileOutputStream(outputPath + sep +outputFileName));
            document.open();
            for (int i = 0; i < files.length; i++) {
                reader = new PdfReader(files[i]);
                int numberOfPages = reader.getNumberOfPages();
                for (int j = 1; j <= numberOfPages; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } finally {
            if (document != null)
                document.close();
            if (reader != null)
                reader.close();
            if (copy != null)
                copy.close();
        }
    }

    public static void mergePDF(String[] files, String targetPath) {
        String sep = File.separator;
        Document document = null;
        PdfCopy copy = null;
        PdfReader reader = null;
        try {
            document = new Document();
            copy = new PdfCopy(document, new FileOutputStream(targetPath));
            document.open();
            for (int i = 0; i < files.length; i++) {
                reader = new PdfReader(files[i]);
                int numberOfPages = reader.getNumberOfPages();
                for (int j = 1; j <= numberOfPages; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
                reader.close();
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } finally {
            if (document != null)
                document.close();
            if (reader != null)
                reader.close();
            if (copy != null)
                copy.close();
        }
    }

    public static void generatePdf(Map<String, Object> map,String filePath,String fileName) throws Exception {
        Object sexObj = map.get("sex");
        Object ageObj = map.get("age");
        Object widthObj = map.get("weight");
        Object heightObj = map.get("height");

        map.put("sexName", NormalRangeUtil.sexStyle(sexObj));
        map.put("weightRange", NormalRangeUtil.weightRange(heightObj));
        map.put("fatRateRange", NormalRangeUtil.fatRateRange(ageObj, sexObj));
        map.put("fatRange", NormalRangeUtil.fatRange(ageObj, sexObj, widthObj));
        map.put("waterRateRange", NormalRangeUtil.waterRateRange(sexObj));
        map.put("waterRange", NormalRangeUtil.waterRange(sexObj, widthObj));
        map.put("basalMetabolismRange", NormalRangeUtil.basalMetabolismRange(sexObj, ageObj));
        map.put("weightStateName", NormalRangeUtil.styleStatus(map.get("weightState")));
        map.put("hwBmiStateName", NormalRangeUtil.hwBmiStateStyle(map.get("hwBmiState")));
        map.put("templatureStateName", NormalRangeUtil.styleStatus(map.get("templatureState")));
        map.put("leftEyesightStateName", NormalRangeUtil.styleStatus(map.get("leftEyesightState")));
        map.put("rightEyesightStateName", NormalRangeUtil.styleStatus(map.get("rightEyesightState")));
        map.put("pulseRateStateName", NormalRangeUtil.styleStatus(map.get("pulseRateState")));
        map.put("fatRateStateName", NormalRangeUtil.styleStatus(map.get("fatRateState")));
        map.put("fatStateName", NormalRangeUtil.styleStatus(map.get("fatState")));
        map.put("waterRateStateName", NormalRangeUtil.styleStatus(map.get("waterRateState")));
        map.put("basalMetabolismStateName", NormalRangeUtil.styleStatus(map.get("basalMetabolismState")));
        map.put("ecgRateStateName", NormalRangeUtil.styleStatus(map.get("ecgRateState")));
        map.put("heightPressureStateName", NormalRangeUtil.pressureStatus(map.get("heightPressureState")));
        map.put("lowPressureStateName", NormalRangeUtil.pressureStatus(map.get("lowPressureState")));
        map.put("bmiAdvice", NormalRangeUtil.bmiAdvice(map.get("hwBmiState")));
        map.put("fatRateAdvice", NormalRangeUtil.fatRateAdvice(map.get("fatRateState")));
        SetDataUtil.lineDate(map);
        String path_pdf1 = filePath+"/1.pdf";
        String path_pdf2 = filePath+"/2.pdf";
        String path_pdf3 = filePath+"/3.pdf";
        String path_pdf4 = filePath+"/4.pdf";
        String path_pdf5 = filePath+"/5.pdf";
        PdfUtil.contractHandler("pdf_success_1", map, path_pdf1);
        PdfUtil.contractHandler("pdf_success_2", map, path_pdf2);
        SetDataUtil.setTempData(map);
        PdfUtil.contractHandler("pdf_success_3", map, path_pdf3);
        PdfUtil.contractHandler("pdf_success_4", map, path_pdf4);
        PdfUtil.contractHandler("pdf_success_5", map, path_pdf5);
        String[] files = {path_pdf1, path_pdf2, path_pdf3, path_pdf4, path_pdf5};
        PdfUtil.mergePDF(files, filePath + "/" + fileName);
        PdfUtil.deleteFile(path_pdf1);
        PdfUtil.deleteFile(path_pdf2);
        PdfUtil.deleteFile(path_pdf3);
        PdfUtil.deleteFile(path_pdf4);
        PdfUtil.deleteFile(path_pdf5);
    }
}
